package com.kk.crowd.handler;

import com.kk.crowd.api.MysqlRemoteService;
import com.kk.crowd.config.OSSProperties;
import com.kk.crowd.constant.CrowdConstant;
import com.kk.crowd.entity.vo.*;
import com.kk.crowd.util.CrowdUtil;
import com.kk.crowd.util.ResultEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Controller
public class ProjectConsumerHandler {

    @Autowired
    private OSSProperties ossProperties;

    @Autowired
    private MysqlRemoteService mysqlRemoteService;

    @RequestMapping("/get/project/detail/{projectId}")
    public String getProjectDetail(@PathVariable("projectId")Integer projectId, Model model){
        ResultEntity<DetailProjectVO> resultEntity = mysqlRemoteService.getDetailProjectVORemote (projectId);
        if (ResultEntity.SUCCESS.equals (resultEntity.getResult ())){
            DetailProjectVO detailProjectVO = resultEntity.getData ( );
            model.addAttribute ("detailProjectVO",detailProjectVO);
        }
        return "project-show-detail";

    }

    @RequestMapping("/create/confirm")
    public String saveConfirm(ModelMap modelMap, HttpSession session,
                              MemberConfirmInfoVO memberConfirmInfoVO){
        // 1.从 Session 域读取之前临时存储的 ProjectVO 对象
        ProjectVO projectVO = (ProjectVO) session.getAttribute (CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);

        // 2.如果 projectVO 为 null
        if (projectVO==null){
            // 控制台可以看到当前临时对象丢失
            throw new RuntimeException(CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
        }

        // 3.将确认信息数据设置到 projectVO 对象中
        projectVO.setMemberConfirmInfoVO (memberConfirmInfoVO);

        // 4.从 Session 域读取当前登录的用户
        MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute (CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
        Integer memberId = memberLoginVO.getId ( );

        // 5.调用远程方法保存 projectVO 对象
        ResultEntity<String> saveResultEntity = mysqlRemoteService.saveProjectVORemote(projectVO,memberId);

        // 6.判断远程的保存操作是否成功
        String result = saveResultEntity.getResult ( );
        if (ResultEntity.FAILED.equals (result)){
            ResultEntity.failed (saveResultEntity.getMessage ());
            return "project-confirm";
        }

        // 7.将临时的 ProjectVO 对象从 Session 域移除
        session.removeAttribute (CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);

        // 8.如果远程保存成功则跳转到最终完成页面
        return "redirect:http://www.crowd.com/project/create/success";
    }


    /**
     * 保存回报信息数据
     * @param returnVO
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping("/create/save/return.json")
    public ResultEntity<String> saveReturn(ReturnVO returnVO,HttpSession session){

        try {
            // 1.从 session 域中读取之前缓存的 ProjectVO 对象
            ProjectVO projectVO = (ProjectVO) session.getAttribute (CrowdConstant.ATTR_NAME_TEMPLE_PROJECT);
            // 2.判断 projectVO 是否为 null
            if (projectVO==null){
                ResultEntity.failed (CrowdConstant.MESSAGE_TEMPLE_PROJECT_MISSING);
            }
            // 3.从 projectVO 对象中获取存储回报信息的集合
            List<ReturnVO> returnVOList = projectVO.getReturnVOList ( );

            // 4.判断 returnVOList 集合是否有效
            if (returnVOList==null || returnVOList.size ()==0){
                // 5.创建集合对象对 returnVOList 进行初始化
                returnVOList = new ArrayList<ReturnVO> ();
                // 6.为了让以后能够正常使用这个集合，设置到 projectVO 对象中
                projectVO.setReturnVOList (returnVOList);
            }

            // 7.将收集了表单数据的 returnVO 对象存入集合
            returnVOList.add (returnVO);

            // 8.把数据有变化的 ProjectVO 对象重新存入 Session 域，以确保新的数据最终能够 存入 Redis
            session.setAttribute (CrowdConstant.ATTR_NAME_TEMPLE_PROJECT,projectVO);

            // 9.所有操作成功完成返回成功
            return ResultEntity.successWithoutData ();
        } catch (Exception e) {
            e.printStackTrace ( );
            return ResultEntity.failed (e.getMessage ());
        }
    }


    /**
     * 接收 回报(project-return)页面异步上传的图片
     *
     * @param returnPicture
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/create/upload/return/picture.json")
    public ResultEntity<String> upload(
            // 接收用户上传的文件
            @RequestParam("returnPicture") MultipartFile returnPicture) throws IOException {

        // 1.执行文件上传
        ResultEntity<String> uploadReturnPicResultEntity = CrowdUtil.uploadFileToOss (
                ossProperties.getEndPoint ( ),
                ossProperties.getAccessKeyId ( ),
                ossProperties.getAccessKeySecret ( ),
                returnPicture.getInputStream ( ),
                ossProperties.getBucketName ( ),
                ossProperties.getBucketDomain ( ),
                returnPicture.getOriginalFilename ( ));
        // 2.返回上传的结果
        return uploadReturnPicResultEntity;
    }


    /**
     * 保存图片（头图和详细图片到 oss对象存储服务器）和 项目发起人信息
     *
     * @param projectVO
     * @param headerPicture
     * @param detailPictureList
     * @param session
     * @param modelMap
     * @return
     * @throws IOException
     */
    @RequestMapping("/create/project/information")
    public String saveProjectBasicInfo(
            // 接收除了上传图片之外的其他普通数据
            ProjectVO projectVO,
            // 接收上传的头图
            MultipartFile headerPicture,
            // 接收上传的详情图片
            List<MultipartFile> detailPictureList,
            // 用来将收集了一部分数据的 ProjectVO 对象存入 Session 域
            HttpSession session,
            // 用来在当前操作失败后返回上一个表单页面时携带提示消息
            ModelMap modelMap
    ) throws IOException {

        // 一、完成头图上传
        // 1.获取当前 headerPicture 对象是否为空
        boolean headerPictureIsEmpty = headerPicture.isEmpty ( );

        if (!headerPictureIsEmpty) {
            // 2.如果用户确实上传了有内容的文件，则执行上传
            ResultEntity<String> uploadHeaderPicResultEntity = CrowdUtil.uploadFileToOss (ossProperties.getEndPoint ( ),
                    ossProperties.getAccessKeyId ( ),
                    ossProperties.getAccessKeySecret ( ),
                    headerPicture.getInputStream ( ),
                    ossProperties.getBucketName ( ),
                    ossProperties.getBucketDomain ( ),
                    headerPicture.getOriginalFilename ( ));

            String result = uploadHeaderPicResultEntity.getResult ( );

            // 3.判断头图是否上传成功
            if (ResultEntity.SUCCESS.equals (result)) {
                // 4.从返回数据中获取图片访问路径
                String headerPicturePath = uploadHeaderPicResultEntity.getData ( );

                // 5.存入PrijectVo对象中
                projectVO.setHeaderPicturePath (headerPicturePath);

            } else {
                // 7.如果上传失败则返回到表单页面并显示错误消息
                modelMap.addAttribute (CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_EMPTY);
                return "project-launch";
            }
        } else {
            // 8.如果没有上传头图则返回到表单页面并显示错误消息
            modelMap.addAttribute (CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_HEADER_PIC_EMPTY);
            return "project-launch";
        }

        // 二、上传详情图片
        // 1.创建一个用来存放详情图片路径的集合
        ArrayList<String> detailPicturePathList = new ArrayList<String> ( );

        // 2.检查 detailPictureList 是否有效
        if (detailPictureList == null || detailPictureList.size ( ) == 0) {
            modelMap.addAttribute (CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);
            return "project-launch";
        }
        // 3.遍历 detailPictureList 集合
        for (MultipartFile detailPicture : detailPictureList) {
            // 4.当前 detailPicture 是否为空
            if (detailPicture.isEmpty ( )) {
                // 5.检测到详情图片中单个文件为空也是回去显示错误消息
                modelMap.addAttribute (CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_EMPTY);
                return "project-launch";
            }
            // 6.执行上传
            ResultEntity<String> detailUploadResultEntity = CrowdUtil.uploadFileToOss (
                    ossProperties.getEndPoint ( ),
                    ossProperties.getAccessKeyId ( ),
                    ossProperties.getAccessKeySecret ( ),
                    detailPicture.getInputStream ( ),
                    ossProperties.getBucketName ( ),
                    ossProperties.getBucketDomain ( ),
                    detailPicture.getOriginalFilename ( ));

            // 7.检查上传结果
            String detailUploadResult = detailUploadResultEntity.getResult ( );

            if (ResultEntity.SUCCESS.equals (detailUploadResult)) {
                String detailPicturePath = detailUploadResultEntity.getData ( );
                // 8.收集刚刚上传的图片的访问路径
                detailPicturePathList.add (detailPicturePath);
            } else {
                // 9.如果上传失败则返回到表单页面并显示错误消息
                modelMap.addAttribute (CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_DETAIL_PIC_UPLOAD_FAILED);
                return "project-launch";
            }
        }

        // 10.将存放了详情图片访问路径的集合存入 ProjectVO 中
        projectVO.setDetailPicturePathList (detailPicturePathList);

        // 三、后续操作
        // 1.将 ProjectVO 对象存入 Session 域
        session.setAttribute (CrowdConstant.ATTR_NAME_TEMPLE_PROJECT, projectVO);

        // 2.以完整的访问路径前往下一个收集回报信息的页面
        return "redirect:http://www.crowd.com/project/return/info/page";
    }
}
